package iks.render.anim
{
	import flash.display.*;
	import flash.geom.*;
	import iks.iface.*;
	import iks.render.anim.*;
	import iks.utils.*;
	
	/**
	 * 关节段类
	 * @author StefanieKaka
	 */
	public class BaseSegment extends Sprite implements IKDispose
	{
		
		/**
		 * 构造函数, 基础点坐标值是以关节矩形框左上角为坐标原点
		 * @param	width 宽度
		 * @param	height 高度
		 * @param	baseX 基础点的x坐标
		 * @param	baseY 基础点的y坐标
		 */
		public function BaseSegment(width : Number, height : Number, baseX : Number, baseY : Number)
		{
			if (baseX < 0 || baseX > width || baseY < 0 || baseY > height)
				throw new ArgumentError("BaseSegment: 指定关节的基础点参数无效");
			
			m_segWidth = width;
			m_segHeight = height;
			m_basePoint = new Point(baseX, baseY);
			m_joints = new Vector.<Point>();
		}
		
		/**
		 * 添加结合点, 结合点坐标值是以关节矩形框左上角为坐标原点
		 * @param	jointX 结合点的x坐标
		 * @param	jointY 结合点的y坐标
		 */
		public function addJoint(jointX : Number, jointY : Number) : void
		{
			if (jointX < 0 || jointX > m_segWidth || jointY < 0 || jointY > m_segHeight)
				throw new ArgumentError("BaseSegment.addJoint: 指定关节的结合点参数无效");
			
			m_joints.push(new Point(jointX, jointY));
		}
		
		/**
		 * 绘制关节图形
		 * @param	graphics Graphics对象
		 */
		public function drawSegment(jointRadius : Number = 5, ellipseW : Number = 0, ellipseH : Number = 0, lineColor : uint = 0x000000, fillColor : uint = 0xffffff, baseColor : uint = 0xff0000) : void
		{
			this.graphics.clear();
			
			// 绘制主体
			var origin : Point = new Point(-m_basePoint.x, -m_basePoint.y);
			this.graphics.lineStyle(0, lineColor);
			this.graphics.beginFill(fillColor);
			this.graphics.drawRoundRect(origin.x, origin.y, m_segWidth, m_segHeight, ellipseW, ellipseH);
			this.graphics.endFill();
			
			// 绘制关节点
			this.graphics.beginFill(baseColor);
			this.graphics.drawCircle(origin.x + m_basePoint.x, origin.y + m_basePoint.y, jointRadius);
			this.graphics.endFill();
			for each (var p : Point in m_joints)
			{
				this.graphics.beginFill(baseColor);
				this.graphics.drawCircle(origin.x + p.x, origin.y + p.y, jointRadius);
				this.graphics.endFill();
			}
		}
		
		/**
		 * 根据索引获得指定结合点在容器中的坐标
		 * @param	index 结合点的索引
		 * @return 结合点在容器中坐标
		 */
		public function getPin(index : int) : Point
		{
			var joint : Point = m_joints[index];
			var pin : Point = new Point(joint.x, joint.y);
			pin.x = (pin.x - m_basePoint.x) * this.scaleX;
			pin.y = (pin.y - m_basePoint.y) * this.scaleY;
			
			var radian : Number = Math.PI * this.rotation / 180.0;
			var cos : Number = Math.cos(radian);
			var sin : Number = Math.sin(radian);
			var dx : Number = cos * pin.x - sin * pin.y;
			var dy : Number = cos * pin.y + sin * pin.x;
			
			pin.x = this.x + dx;
			pin.y = this.y + dy;
			
			return pin;
		}
		
		/**
		 * 根据结合点的索引添加显示对象
		 * @param	index 结合点的索引
		 * @param	obj 添加的显示对象
		 */
		public function addChildToPin(index : int, obj : DisplayObject) : void
		{
			var pin : Point = m_joints[index];
			var tx : Number = pin.x - m_basePoint.x;
			var ty : Number = pin.y - m_basePoint.y;
			obj.x = tx;
			obj.y = ty;
			this.addChild(obj);
		}
		
		/**
		 * 获得基准点的x位置
		 */
		public function get basePointX() : Number
		{
			return m_basePoint.x;
		}
		
		/**
		 * 获得基准点的y位置
		 */
		public function get basePointY() : Number
		{
			return m_basePoint.y;
		}
		
		/**
		 * 设置/获取关节关联的动画
		 */
		public function set animator(value : KSpriteAnimator) : void
		{
			// 先移除之前的动画元件
			if (m_animator != null)
				this.removeChild(m_animator);
			m_animator = value;
				
			// 添加新的动画元件
			if (value != null)
			{
				m_animator.setAnchorPoint(m_basePoint.x / m_segWidth, m_basePoint.y / m_segHeight);
				this.addChild(m_animator);
			}
		}
		
		public function get animator() : KSpriteAnimator
		{
			return m_animator;
		}
		
///////////////////////////////////////////////////////////////////////////////////////////////////
// 实现IKDispose接口
///////////////////////////////////////////////////////////////////////////////////////////////////
		
		public function dispose() : void
		{
			if (m_isDisposed)
				return;
			m_isDisposed = true;
			
			this.animator = null;
			
			m_joints.splice(0, m_joints.length);
			m_joints = null;
			
			Helper.removeChildren(this);
		}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 私有域
///////////////////////////////////////////////////////////////////////////////////////////////////
		
		private var m_segWidth : Number = NaN;
		private var m_segHeight : Number = NaN;
		private var m_basePoint : Point = null;
		private var m_joints : Vector.<Point> = null;
		private var m_animator : KSpriteAnimator = null;
		private var m_isDisposed : Boolean = false;
	}

}